import utils from "js/core/utils";
import { TimerModel, TimerTaskModel } from "js/model/timerModel";

const timeInterval = 20; // 设置计时器步长 100毫秒

export default class TimerHandle {
    timerInfo: TimerModel;
    perTime: number;
    timeCoe: number;

    constructor() {
        this.timerInfo = new TimerModel({});
        this.timeCoe = 1;
    }

    async start() {
        this.timerInfo.state = 1; // 计时器开关，值为1的时候打开
        this.perTime = new Date().getTime();

        while (this.timerInfo.state === 1) {
            let nodeTime = new Date().getTime();
            let timeCount = this.timerInfo.timeCount;

            if (timeCount * timeInterval < (nodeTime - this.perTime)) {
                let timeQueueItems = this.timerInfo.timeQueue[timeCount];

                // 遍历时间点上的计时器任务
                if (timeQueueItems) {
                    for (let i = 0; i < timeQueueItems.length; i++) {
                        let task: TimerTaskModel = timeQueueItems[i];

                        // 判断任务是否开启
                        if (task.disable === false && this.timerInfo.state === 1) {
                            await task.fn();

                            if (task.count === 0) {
                                this.setInterval(task.fn, task.interval);
                            }
                        }
                    }

                    // 释放数据
                    delete this.timerInfo.timeQueue[timeCount];
                }

                this.timerInfo.timeCount += 1;
            } else {
                await utils.sleep(timeInterval); // 等待一个计时器步长时间
            }
        }
    }

    getTime() {
        let timerInfo = this.timerInfo;
        let timeCount = timerInfo.timeCount;
        return timeInterval * timeCount;
    }

    getTimerEndTime(id) {
        let timerInfo = this.timerInfo;
        let item: TimerTaskModel = timerInfo.timeQueueObject[id];
        return timeInterval * item.time;
    }

    setTimeout(fn: any, interval: number | any) {
        let intervalValue;

        if (typeof interval === 'number') {
            intervalValue = interval;
        } else if (typeof interval === 'function') {
            intervalValue = interval();
        }

        let timerInfo = this.timerInfo;
        let timeCount = timerInfo.timeCount;
        let endTimeCount = Math.floor(timeCount + intervalValue / timeInterval / this.timeCoe);

        if (endTimeCount < 1) {
            endTimeCount = 1;
        }

        let timeQueueItems = timerInfo.timeQueue[endTimeCount];

        if (!timeQueueItems) {
            timerInfo.timeQueue[endTimeCount] = [];
            timeQueueItems = timerInfo.timeQueue[endTimeCount];
        }

        let taskItem = new TimerTaskModel();
        taskItem.id = timerInfo.taskAutoID++;
        taskItem.fn = fn;
        taskItem.count = 1;
        taskItem.interval = interval;
        taskItem.time = endTimeCount;
        timeQueueItems.push(taskItem);
        timerInfo.timeQueueObject[taskItem.id] = taskItem;

        return taskItem.id;
    }

    // 设置间隔
    setInterval(fn: any, interval: number | any) {
        let intervalValue; // 毫秒时间

        if (typeof interval === 'number') {
            intervalValue = interval;
        } else if (typeof interval === 'function') {
            intervalValue = interval();
        }

        let timerInfo = this.timerInfo;
        let timeCount = timerInfo.timeCount;
        let endTimeCount = Math.floor(timeCount + intervalValue / timeInterval / this.timeCoe);

        if (endTimeCount < 1) {
            endTimeCount = 1;
        }

        let timeQueueItems = timerInfo.timeQueue[endTimeCount];

        if (!timeQueueItems) {
            timerInfo.timeQueue[endTimeCount] = [];
            timeQueueItems = timerInfo.timeQueue[endTimeCount];
        }

        let taskItem = new TimerTaskModel();
        taskItem.id = timerInfo.taskAutoID++;
        taskItem.fn = fn;
        taskItem.count = 0;
        taskItem.interval = interval;
        taskItem.time = endTimeCount;
        timeQueueItems.push(taskItem);
        timerInfo.timeQueueObject[taskItem.id] = taskItem;

        return taskItem.id;
    }

    clearTimeout(id) {
        let timerInfo = this.timerInfo;
        let item = timerInfo.timeQueueObject[id];

        if (item) {
            item.disable = true;
        }
    }

    stop() {
        this.timerInfo.state = 0; // 设置计时器状态为停止
    }
}